package cn.com.surker.lab.service.impl;

import cn.com.surker.common.MessageCenterException;
import cn.com.surker.enums.material.MaterialBreedTypeEnum;
import cn.com.surker.enums.material.SysMaterialTypeEnum;
import cn.com.surker.enums.system.DataBaseEnum;
import cn.com.surker.excel.ExcelReportUtils;
import cn.com.surker.lab.dao.LabExpendDao;
import cn.com.surker.lab.entity.LabExpend;
import cn.com.surker.lab.service.LabExpendService;
import cn.com.surker.lab.vo.LabExpendVo;
import cn.com.surker.production.dao.IndentDispatchDao;
import cn.com.surker.system.dao.DataSourceInfoDao;
import cn.com.surker.system.entity.DataSourceInfo;
import cn.com.surker.util.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 工控机消耗表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2024-11-05
 */
public abstract class LabExpendBaseImpl extends ServiceImpl<LabExpendDao, LabExpend> implements LabExpendService {

	@Resource
	protected LabExpendDao labExpendDao;
	@Resource
	protected DataSourceInfoDao dsDao;
	@Resource
	protected IndentDispatchDao indentDispatchDao;

	@Override
	protected Class<LabExpend> currentModelClass() {
		return LabExpend.class;
	}

	/**
	 * 料仓消耗统计
	 * @param orgId
	 * @param lineId 生产线ID
	 * @param storageId 仓位ID
	 * @param materialId 材料ID
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public List<LabExpendVo> findStorageExpend(Long orgId, Long lineId, Long storageId, Long materialId, String startTime,
											   String endTime, Integer type, Integer materialType, Integer breedType) {
		if (StringUtils.isNull(orgId))
			return null;
		DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId, DataBaseEnum.MYSQL.getCode());
		if (ds == null || ds.getType() != 0)
			return null;
		List<LabExpendVo> expendVoList = labExpendDao.findStorageExpendV1(ds.getCode(), lineId, storageId,
				materialId, startTime, endTime,materialType, breedType);
		if (!StringUtils.isNull(type) && type == 1){
			return convertMaterialType(expendVoList);
		} else {
			return expendVoList;
		}
	}

	/**
	 * 按强度查询原材平均消耗
	 * @param searchVal
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public List<Map<String, Object>> findStrengthDosage(String dbCode, String searchVal, Long indentId, Long lineId, String startTime, String endTime) {
		if (StringUtils.isNull(dbCode))
			return null;
		List<LabExpendVo> expendVoList = labExpendDao.findStrengthDosage(dbCode, searchVal, indentId, lineId, startTime, endTime);
		if (expendVoList == null || expendVoList.size() == 0)
			return null;
		Map<Integer, String> breedMap = new HashMap<>();
		for (int i = 0; i < MaterialBreedTypeEnum.values().length; i++) {
//			if (MaterialBreedTypeEnum.values()[i].getCode() > 0) {
				breedMap.put(MaterialBreedTypeEnum.values()[i].getCode(),MaterialBreedTypeEnum.values()[i].getAttr());
//			}
		}
		Map<String, Map<String, Object>> strengthMap = new LinkedHashMap<>();
		for (LabExpendVo expendVo : expendVoList) {
			if (StringUtils.isNull(expendVo.getStrength()) || StringUtils.isNull(expendVo.getMaterialBreedType()))
				continue;
			Integer breedType = expendVo.getMaterialBreedType();//材料品类
			if (!breedMap.containsKey(breedType))
				continue;
//			if (expendVo.getMaterialBreedType() == MaterialBreedTypeEnum.QT.getCode()) {
//
//				continue;
//			}
			String strength = expendVo.getStrength();//强度
			Double proStere = StringUtils.formatDouble(expendVo.getProStere(), 2);//发货方量
			Double realDosage = StringUtils.formatDouble(expendVo.getRealDosage(), 2);//实际下料量
			String breedKey = breedMap.get(breedType);
			if (strengthMap.containsKey(strength)) {
				Map<String, Object> tempMap = strengthMap.get(strength);
				Double proStere_ = StringUtils.convertDouble(tempMap.get("proStere"));
				Double dosage = StringUtils.formatDouble(StringUtils.convertDouble(tempMap.get("dosage")) + realDosage, 2);
				tempMap.put(breedKey, realDosage);
				if (proStere_ < proStere)
					tempMap.put("proStere", proStere);
				tempMap.put("dosage", dosage);
				strengthMap.put(strength, tempMap);
			} else {
				Map<String, Object> tempMap = buildBreedMap();
				tempMap.put("strength", strength);
				tempMap.put("proStere", proStere);
				tempMap.put(breedKey, realDosage);
				tempMap.put("dosage", realDosage);
				strengthMap.put(strength, tempMap);
			}
		}
		if (strengthMap == null || strengthMap.keySet().size() == 0)
			return null;
		List<Map<String, Object>> list = new ArrayList<>();
		for (String key : strengthMap.keySet()) {
			list.add(strengthMap.get(key));
		}
		return list;
	}

	private Map<String, Object> buildBreedMap() {
		Map<String, Object> valMap = new LinkedHashMap<>();
		for (int i = 0; i < MaterialBreedTypeEnum.values().length; i++) {
			if (MaterialBreedTypeEnum.values()[i].getCode() > 0) {
				valMap.put(MaterialBreedTypeEnum.values()[i].getAttr(), 0);
			}
		}
		return valMap;
	}

	/**
	 * 导出原材购进明细报表
	 * @param sheetName
	 * @param expendList
	 * @return
	 */
	public XSSFWorkbook exportStorageExpend(String sheetName, String title, List<LabExpendVo> expendList, Integer type) {
		if (expendList == null || expendList.size() == 0)
			throw new MessageCenterException("没有任何导出数据~！");
		XSSFWorkbook hw = new XSSFWorkbook();
		List<Map<String, Object>> list = new ArrayList<>();
		List<String> keyList = new ArrayList<>();
		Map<Integer, String> materialTypeMap = new HashMap<>();
		Map<Integer, String> materialBreedTypeMap = new HashMap<>();
		for (int i = 0; i < SysMaterialTypeEnum.values().length; i++) {
			if (SysMaterialTypeEnum.values()[i].getCode() > 1 && SysMaterialTypeEnum.values()[i].getCode() < 11) {
				materialTypeMap.put(SysMaterialTypeEnum.values()[i].getCode(), SysMaterialTypeEnum.values()[i].getDescription());
			}
		}
		for (int i = 0; i < MaterialBreedTypeEnum.values().length; i++) {
			materialBreedTypeMap.put(MaterialBreedTypeEnum.values()[i].getCode(), MaterialBreedTypeEnum.values()[i].getDescription());
		}
		if (!StringUtils.isNull(type) && type == 1) {
			for (int i = 0; i < expendList.size(); i++) {
				LabExpendVo expendVo = expendList.get(i);
				Map<String, Object> temp = new LinkedHashMap<>();
				temp.put("nameNorms", expendVo.getNameNorms());
				temp.put("labQuantity", expendVo.getLabQuantity());
				temp.put("setQuantity", expendVo.getSetQuantity());
				temp.put("realQuantity", expendVo.getRealQuantity());
				temp.put("errorValue", expendVo.getErrorValue());
				temp.put("errorRate", expendVo.getErrorRate());
				temp.put("materialType", StringUtils.convertString(materialTypeMap.get(expendVo.getMaterialType())));
				temp.put("materialBreedType", StringUtils.convertString(materialBreedTypeMap.get(expendVo.getMaterialBreedType())));
				list.add(temp);
			}
			Object[] columns = {"材料","配比用量(吨)","工控设定量(吨)","工控实际用量(吨)","误差值(吨)","误差率(%)", "材料类型","材料品种"};
			keyList.add("labQuantity");
			keyList.add("setQuantity");
			keyList.add("realQuantity");
			keyList.add("errorValue");
			keyList.add("errorRate");
			hw = ExcelReportUtils.exportTotalReport(sheetName, title, columns, keyList, list, hw);
			return hw;
		} else {
			for (int i = 0; i < expendList.size(); i++) {
				LabExpendVo expendVo = expendList.get(i);
				String isAuto = "自动";
				Map<String, Object> temp = new LinkedHashMap<>();
				if (!StringUtils.isNull(expendVo.getType()) && expendVo.getType() == 1)
					isAuto = "手动";
				temp.put("lineName", expendVo.getLineName());
				temp.put("storageName", expendVo.getStorageName());
				temp.put("nameNorms", expendVo.getNameNorms());
				temp.put("labQuantity", expendVo.getLabQuantity());
				temp.put("setQuantity", expendVo.getSetQuantity());
				temp.put("realQuantity", expendVo.getRealQuantity());
				temp.put("errorValue", expendVo.getErrorValue());
				temp.put("errorRate", expendVo.getErrorRate());
				temp.put("isAuto", isAuto);
				temp.put("materialType", StringUtils.convertString(materialTypeMap.get(expendVo.getMaterialType())));
				temp.put("materialBreedType", StringUtils.convertString(materialBreedTypeMap.get(expendVo.getMaterialBreedType())));
				list.add(temp);
			}
			Object[] columns = {"生产线","仓位","材料","配比用量(吨)","工控设定量(吨)","工控实际用量(吨)","误差值(吨)","误差率(%)",
					"类型","材料类型","材料品种"};
			keyList.add("labQuantity");
			keyList.add("setQuantity");
			keyList.add("realQuantity");
			keyList.add("errorValue");
			keyList.add("errorRate");
			hw = ExcelReportUtils.exportTotalReport(sheetName, title, columns, keyList, list, hw);
			return hw;
		}
	}

	/**
	 * 导出料仓消耗报表
	 * @param sheetName
	 * @param title
	 * @param expendList
	 * @return
	 */
	public XSSFWorkbook exportDosageExpend(String sheetName, String title, List<Map<String, Object>> expendList) {
		if (expendList == null || expendList.size() == 0)
			return null;

		List<String> keyList = new ArrayList<>();
		List<Map<String, Object>> list = new ArrayList<>();
		for (Map<String, Object> map : expendList) {
			String strength = StringUtils.convertString(map.get("strength"));
			Double proStere = StringUtils.convertDouble(map.get("proStere"));//发货量
			Double dosage = StringUtils.convertDouble(map.get("dosage"));//容重
			Double SN = StringUtils.convertDouble(map.get("SN"));//水泥
			Double JZS = StringUtils.convertDouble(map.get("JZS"));//机制砂
			Double SZ01 = StringUtils.convertDouble(map.get("SZ01"));//石子01
			Double SZ12 = StringUtils.convertDouble(map.get("SZ12"));//石子12
			Double MH = StringUtils.convertDouble(map.get("MH"));//煤灰
			Double SF = StringUtils.convertDouble(map.get("SF"));//石粉
			Double KF = StringUtils.convertDouble(map.get("KF"));//矿粉
			Double WJJ = StringUtils.convertDouble(map.get("WJJ"));//外加剂
			Double PZJ = StringUtils.convertDouble(map.get("PZJ"));//膨胀剂
			Double ZSJ = StringUtils.convertDouble(map.get("ZSJ"));//增塑剂
			Double TJJ = StringUtils.convertDouble(map.get("TJJ"));//调节剂
			Double HS = StringUtils.convertDouble(map.get("HS"));//河沙
			Double PS = StringUtils.convertDouble(map.get("PS"));//片石
			Double QT = StringUtils.convertDouble(map.get("QT"));//水
			Map<String, Object> temp = new LinkedHashMap<>();
			temp.put("strength", strength);
			temp.put("proStere", proStere);
			temp.put("dosage", dosage);
			temp.put("SN", SN);
			temp.put("JZS", JZS);
			temp.put("SZ01", SZ01);
			temp.put("SZ12", SZ12);
			temp.put("MH", MH);
			temp.put("SF", SF);
			temp.put("KF", KF);
			temp.put("WJJ", WJJ);
			temp.put("PZJ", PZJ);
			temp.put("ZSJ", ZSJ);
			temp.put("TJJ", TJJ);
			temp.put("HS", HS);
			temp.put("PS", PS);
			temp.put("QT", QT);
			list.add(temp);
		}
		Object[] columns = {"强度","发货量","容重(kg)","水泥(kg)","机制砂(kg)","石子01(kg)","石子12(kg)","煤灰(kg)",
				"石粉(kg)","矿粉(kg)","外加剂(kg)","膨胀剂(kg)","增塑剂(kg)","调节剂(kg)","河沙(kg)","片石(kg)","水(kg)"};
		keyList.add("proStere");
		keyList.add("dosage");
		keyList.add("SN");
		keyList.add("JZS");
		keyList.add("SZ01");
		keyList.add("SZ12");
		keyList.add("MH");
		keyList.add("SF");
		keyList.add("KF");
		keyList.add("WJJ");
		keyList.add("PZJ");
		keyList.add("ZSJ");
		keyList.add("TJJ");
		keyList.add("HS");
		keyList.add("PS");
		keyList.add("QT");
		XSSFWorkbook hw = ExcelReportUtils.exportTotalReport(sheetName, title, columns, keyList, list, new XSSFWorkbook());
		return hw;
	}
	/**
	 * 转换材料类型
	 * @param expendList
	 * @return
	 */
	private List<LabExpendVo> convertMaterialType(List<LabExpendVo> expendList) {
		if (expendList == null || expendList.size() == 0)
			return null;
		List<LabExpendVo> resultList = new ArrayList<>();
		Map<Long, LabExpendVo> expendVoMap = new LinkedHashMap<>();
		for (int i = 0; i < expendList.size(); i++) {
			LabExpendVo expendVo = expendList.get(i);
			Long materialId = expendVo.getMaterialId();
			if (expendVoMap.containsKey(materialId)) {
				LabExpendVo tempVo = expendVoMap.get(materialId);
				Double labQuantity = StringUtils.formatDouble(StringUtils.convertDouble(tempVo.getLabQuantity()) * 1000 + StringUtils.convertDouble(expendVo.getLabQuantity()) * 1000, 2);
				Double setQuantity = StringUtils.formatDouble(StringUtils.convertDouble(tempVo.getSetQuantity()) * 1000 + StringUtils.convertDouble(expendVo.getSetQuantity()) * 1000, 2);
				Double realQuantity = StringUtils.formatDouble(StringUtils.convertDouble(tempVo.getRealQuantity()) * 1000 + StringUtils.convertDouble(expendVo.getRealQuantity()) * 1000, 2);
				Double errorValue = StringUtils.formatDouble(realQuantity - labQuantity, 2);
				Double errorRate = 0.0;
				if (!StringUtils.isNull(errorValue) && errorValue != 0
						&& !StringUtils.isNull(labQuantity) && labQuantity.doubleValue() != 0)
					errorRate = StringUtils.formatDouble(StringUtils.convertDouble(errorValue) / StringUtils.convertDouble(labQuantity), 2);
				tempVo.setLabQuantity(labQuantity);
				tempVo.setSetQuantity(setQuantity);
				tempVo.setRealQuantity(realQuantity);
				tempVo.setErrorValue(errorValue);
				tempVo.setErrorRate(errorRate);
				expendVoMap.put(materialId, tempVo);
			} else {
				expendVoMap.put(materialId, expendVo);
			}
		}
		for (Long key : expendVoMap.keySet()) {
			resultList.add(expendVoMap.get(key));
		}
		return resultList;
	}

}